﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using System.IO.IsolatedStorage;
using System.IO;
using System.Threading;
using System.Text;

namespace NGA
{
    public delegate bool HttpHandlerResponse(String result);

    public class HttpHandler
    {
        private Uri _uri;
        private string _parametersString;
        private HttpHandlerResponse _resultResponse;
        private String _cookies = string.Empty;
        static CookieCollection _cookieJar;
        private Encoding _encoder;

        private const string _settingLabelAppCookie = "cookie";

        public HttpHandler(String url, String param, Encoding encoder, HttpHandlerResponse response)
        {
            _uri = new Uri(url);
            _parametersString = param;
            _resultResponse = new HttpHandlerResponse(response);
            _encoder = encoder;
            // HttpWebRequest
            //HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_url);
            HttpWebRequest request = HttpWebRequest.CreateHttp(_uri);
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            request.CookieContainer = new CookieContainer();
            request.Accept = "image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, image/pjpeg, application/x-ms-xbap, application/x-shockwave-flash, */*";

            // add cookie to header
            var settings = IsolatedStorageSettings.ApplicationSettings;
            if (!settings.Contains(_settingLabelAppCookie)) //exist?
            {
                settings.Add(_settingLabelAppCookie, string.Empty);
                settings.Save();
                if (_cookieJar != null)
                {
                    _cookies = string.Empty;
                    foreach (Cookie c in _cookieJar)
                    {
                        //System.Diagnostics.Debug.WriteLine("Cookie : " + c.Name + " = " + c.Value);
                        _cookies += c.ToString() + ";";
                    }
                }
            }
            _cookies = settings[_settingLabelAppCookie].ToString();
            if (_cookies != string.Empty)
            {
                request.Headers["Cookie"] = _cookies;
            }

            request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), request); 
        }

        private void GetRequestStreamCallback(IAsyncResult asynchronousResult)
        {
            HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;

            if (_parametersString != null)
            {
                Stream postStream = request.EndGetRequestStream(asynchronousResult);
                byte[] byteArray = _encoder.GetBytes(_parametersString);
                // Write to the request stream.
                postStream.Write(byteArray, 0, _parametersString.Length);
                postStream.Close();
            }
            // Start the asynchronous operation to get the response
            //request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
            new Thread( ()=>request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request) ).Start();
        }

        private void GetResponseCallback(IAsyncResult asynchronousResult)
        {
            HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
            
            if (request.HaveResponse)
            {
                HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
                Stream streamResponse = response.GetResponseStream();
                StreamReader streamReader = new StreamReader(streamResponse, _encoder);
                string _result = streamReader.ReadToEnd();
                
                // init cookie
                if (_resultResponse(_result))
                {
                    if (_cookieJar == null)
                    {
                        _cookieJar = request.CookieContainer.GetCookies(_uri);

                        if (_cookieJar != null)
                        {
                            _cookies = string.Empty;
                            foreach (Cookie c in _cookieJar)
                            {
                                //System.Diagnostics.Debug.WriteLine("Cookie : " + c.Name + " = " + c.Value);
                                _cookies += c.ToString() + ";";
                            }
                        }

                        var settings = IsolatedStorageSettings.ApplicationSettings;
                        if (!settings.Contains(_settingLabelAppCookie)) //exist?
                        {
                            settings.Add(_settingLabelAppCookie, _cookies);
                            settings.Save();
                        }
                        else
                        {
                            settings[_settingLabelAppCookie] = _cookies;
                        }
                    }
                }
                else
                {
                    _cookies = string.Empty;
                }

                // Close the stream object
                streamReader.Close();
                streamResponse.Close();
                response.Close();
            }
            else
            {
                Deployment.Current.Dispatcher.BeginInvoke(() => _resultResponse(null));
            }
        }
    }


}